vue源码-2.数据代理


目的

把data属性赋值给vm._data。遍历options里的data属性,通过defineProperty给vm定义属性,vm.xx = xxx触发set方法,set方法通知给vm._data

Vue的数据代理

为什么修改vm的属性值,vm._data里的值会改变呢?
答:进行了数据代理,vue初始化d会对data里的属性进行遍历,对每个属性进行set/get。修改了vm的属性值,触发set方法改变_data里的值

MVVM使用方式

1
2
3
4
5
6
7
// vue相同使用方法
const vm = new MVVM({
data: {
name: 'Ethan'
}
})
vm.name = 'Ethan2'

MVVM实现数据代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function MVVM (options) {
// 保存配置(等价于vue.$options)
this.$options = options
// 保存data(等价于vue._data)
var data = this._data = this.$options.data
var me = this

Object.keys(data).forEach(key => {
// 对指定属性实现代理
me._proxy(key)
})

// 创建编译对象
// this.$compile = new Compile(options.el || document.body, this)
}
MVVM.prototype = {
_proxy: function (key) {
var me = this
// 给vm添加指定属性(等价于vue.name === 'Ethan',所以vue中就有name属性)
Object.defineProperty(me, key, {
configurable: false,
enumerable: true,
get: function proxyGetter() {
return me._data[key]
},
set: function proxySetter(newVal) {
me._data[key] = newVal
}
})
}
}